<%-- 
    Document   : display.jsp
    Created on : Mar 9, 2012, 3:16:35 AM
    Author     : Bradley Carey
--%>

<%@page errorPage="error.jsp" contentType="text/html" pageEncoding="UTF-8" import="org.apache.commons.math3.random.*, java.util.*, org.apache.commons.lang3.StringUtils, org.apache.commons.math3.linear.*, org.apache.commons.math3.stat.descriptive.*" %>
<%@ include file="header.html" %>
<%!
    public double[][] MatrixFromString(String original)
    {
        original = StringUtils.deleteWhitespace(original);
        original = StringUtils.remove(original,"[");
        original = StringUtils.remove(original,"]");
        String[] splitString = StringUtils.split(original, ";");
        ArrayList<String[]> finalValues = new ArrayList<String[]>();
        for(int i=0; i < splitString.length; i++)
            finalValues.add(StringUtils.split(splitString[i],","));
        double[][] matrix = new double[finalValues.size()][finalValues.get(0).length];
        for(int i=0; i < finalValues.size(); i++)
            for(int j=0; j < finalValues.get(i).length; j++)
                matrix[i][j] = Double.parseDouble(finalValues.get(i)[j]);
        return matrix;
    }
%>
        <h1>ACWI</h1>
<%
        String output="";
        String input="";
        int req = Integer.parseInt(request.getParameter("requesttype"));
        switch(req)
        {
            case 1: //rand number
                int rnTotal = Integer.parseInt(request.getParameter("rnTotal"));
                int rnMin = Integer.parseInt(request.getParameter("rnMin"));
                int rnMax = Integer.parseInt(request.getParameter("rnMax"));
                RandomData randomData = new RandomDataImpl();
                Integer[] values = new Integer[rnTotal];
                for (int i = 0; i < rnTotal; i++)
                    values[i] = randomData.nextInt(rnMin, rnMax);
                input = "Generate " + rnTotal + " integers between " + rnMin + " and " + rnMax + ".";
                output = StringUtils.join(values, ", ");
                break;

            case 2: //rand vector
                int rvTotal = Integer.parseInt(request.getParameter("rvTotal"));
                int rvDim = Integer.parseInt(request.getParameter("rvDim"));
                UncorrelatedRandomVectorGenerator vg = new UncorrelatedRandomVectorGenerator(rvDim, new StableRandomGenerator(new JDKRandomGenerator(), 1, 0));
                for(int i = 0; i < rvTotal; i++)
                {
                    double[] rvector = vg.nextVector();
                    output += Arrays.toString(rvector) + "<br>";
                }
                input = "Generate " + rvTotal + " " + rvDim + "-dimensional vectors.";
                break;

            case 3: //rand string
                int rhsLen = Integer.parseInt(request.getParameter("rhsLen"));
                String rhsCrypto = request.getParameter("rhsCrypto");
                RandomDataImpl randomString = new RandomDataImpl();
                if(rhsCrypto != null)
                {
                    output = randomString.nextSecureHexString(rhsLen);
                    input = "Generate random cryptography-secure  string of length " + rhsLen + ".";
                } else {
                    output = randomString.nextHexString(rhsLen);
                    input = "Generate random string of length " + rhsLen + ".";
                }
                break;

            case 4: //rand sample
                String rsList = request.getParameter("rsList");
                int rsTotal = Integer.parseInt(request.getParameter("rsTotal"));
                ArrayList<String> listOfStuff = new ArrayList<String>(Arrays.asList(StringUtils.deleteWhitespace(rsList).split(",")));
                for(int i=0; i < listOfStuff.size(); i++)
                    output += listOfStuff.get(i) + "#";
                RandomData rd = new RandomDataImpl();
                output = StringUtils.join(rd.nextSample(listOfStuff, rsTotal), ", ");
                break;
                
            case 5: // 1-matrix operations
                String moOp = request.getParameter("op");
                String moList = request.getParameter("moList");
                double[][] inM = MatrixFromString(moList);
                Array2DRowRealMatrix realMatrix = new Array2DRowRealMatrix(inM);
                if(moOp.equals("transpose"))
                {
                    input = "Transpose matrix M where M = " + moList;
                    output = StringUtils.removeStart(realMatrix.transpose().toString(), "Array2DRowRealMatrix");
                } else if(moOp.equals("norm")) {
                    input = "Norm(M) where M = " + moList;
                    output = Double.toString(realMatrix.getFrobeniusNorm());
                } else if(moOp.equals("trace")) {
                    input = "Trace(M) where M = " + moList;
                    output = Double.toString(realMatrix.getTrace());
                } else if(moOp.equals("determinant")) {
                    input = "det(M) where M = " + moList;
                    output = Double.toString(new LUDecomposition(realMatrix).getDeterminant());
                } else if(moOp.equals("inverse")) {
                    input = "Inverse of M where M = " + moList;
                    output = StringUtils.removeStart(new LUDecomposition(realMatrix).getSolver().getInverse().toString(), "Array2DRowRealMatrix");
                }
                break;
                
            case 6:
                String mOp = request.getParameter("op");
                String matrixM = request.getParameter("maM");
                String matrixN = request.getParameter("maN");
                double[][] dubM = MatrixFromString(matrixM);
                Array2DRowRealMatrix M = new Array2DRowRealMatrix(dubM);
                if(mOp.equals("addition"))
                {
                    double[][] dubN = MatrixFromString(matrixN);
                    Array2DRowRealMatrix N = new Array2DRowRealMatrix(dubN);
                    Array2DRowRealMatrix add = M.add(N);
                    input = "Calculate M+N where: <br>M = " + matrixM.toString() + "<br>N = " + matrixN.toString();
                    output = "M+N = " + StringUtils.removeStart(add.toString(), "Array2DRowRealMatrix");
                } else if(mOp.equals("subtraction")) {
                    double[][] dubN = MatrixFromString(matrixN);
                    Array2DRowRealMatrix N = new Array2DRowRealMatrix(dubN);
                    Array2DRowRealMatrix subt = M.subtract(N);
                    input = "Calculate M-N where: <br>M = " + matrixM.toString() + "<br>N = " + matrixN.toString();
                    output = "M-N = " + StringUtils.removeStart(subt.toString(), "Array2DRowRealMatrix");
                } else if(mOp.equals("multiplication")) {
                    double[][] dubN = MatrixFromString(matrixN);
                    Array2DRowRealMatrix N = new Array2DRowRealMatrix(dubN);
                    Array2DRowRealMatrix mult = M.multiply(N);
                    input = "Calculate M*N where: <br>M = " + matrixM.toString() + "<br>N = " + matrixN.toString();
                    output = "M*N = " + StringUtils.removeStart(mult.toString(), "Array2DRowRealMatrix");
                } else if(mOp.equals("scalarAdd")) {
                    RealMatrix sAdd = M.scalarAdd(Double.parseDouble(matrixN));
                    input = "Calculate M+N where: <br>M = " + matrixM.toString() + "<br>N = " + matrixN;
                    output = "M+N = " + StringUtils.removeStart(sAdd.toString(), "Array2DRowRealMatrix");
                } else if(mOp.equals("scalarMult")) {
                    RealMatrix sMult = M.scalarMultiply(Double.parseDouble(matrixN));
                    input = "Calculate M*N where: <br>M = " + matrixM.toString() + "<br>N = " + matrixN;
                    output = "M*N = " + StringUtils.removeStart(sMult.toString(), "Array2DRowRealMatrix");
                }
                break;
                
            case 7: // vector algebra
                String vectorOp = request.getParameter("vectorOp");
                String vectorV = request.getParameter("vectorV");
                String vectorW = request.getParameter("vectorW");
                ArrayRealVector v = new RealVectorFormat().parse(vectorV);
                if(vectorOp.equals("addition"))
                {
                    ArrayRealVector w = new RealVectorFormat().parse(vectorW);
                    input = "Compute V+W where:<br> V = " + v.toString() + "<br>W = " + w.toString();
                    output = v.add(w).toString();
                } else if(vectorOp.equals("ebemultiply")) {
                    ArrayRealVector w = new RealVectorFormat().parse(vectorW);
                    input = "Compute V*W using element-by-element multiplication where:<br> V = " + v.toString() + "<br>W = " + w.toString();
                    output = v.ebeMultiply(w).toString();
                } else if(vectorOp.equals("subtraction")) {
                    ArrayRealVector w = new RealVectorFormat().parse(vectorW);
                    input = "Compute V-W where:<br> V = " + v.toString() + "<br>W = " + w.toString();
                    output = v.subtract(w).toString();
                } else if(vectorOp.equals("ebedivide")) {
                    ArrayRealVector w = new RealVectorFormat().parse(vectorW);
                    input = "Compute V/W using element-by-element division where:<br> V = " + v.toString() + "<br>W = " + w.toString();
                    output = v.ebeDivide(w).toString();
                } else if(vectorOp.equals("dotproduct")) {
                    ArrayRealVector w = new RealVectorFormat().parse(vectorW);
                    input = "Compute V·W where:<br> V = " + v.toString() + "<br>W = " + w.toString();
                    output = v.dotProduct(w) + "";
                } else if(vectorOp.equals("scalarAdd")) {
                    input = "Compute V+W where W is a scalar:<br> V = " + v.toString() + "<br>W = " + vectorW;
                    output = v.mapAdd(Double.parseDouble(vectorW)).toString();
                } else if(vectorOp.equals("scalarMult")) {
                    input = "Compute V*W where W is a scalar:<br> V = " + v.toString() + "<br>W = " + vectorW;
                    output = v.mapMultiply(Double.parseDouble(vectorW)).toString();
                } else if(vectorOp.equals("distance")) {
                    ArrayRealVector w = new RealVectorFormat().parse(vectorW);
                    input = "Compute distance between V and W where:<br> V = " + v.toString() + "<br>W = " + w.toString();
                    output = v.getDistance(w) + "";
                } else if(vectorOp.equals("project")) {
                    ArrayRealVector w = new RealVectorFormat().parse(vectorW);
                    input = "Project V onto W where:<br> V = " + v.toString() + "<br>W = " + w.toString();
                    output = v.projection(w).toString();
                } else if(vectorOp.equals("unitize")) {
                    ArrayRealVector w = new RealVectorFormat().parse(vectorW);
                    input = "Unitize vector V where V = " + v.toString();
                    v.unitize();
                    output = v.toString();
                } else if(vectorOp.equals("outerproduct")) {
                    ArrayRealVector w = new RealVectorFormat().parse(vectorW);
                    input = "Computer outer product of V and W where:<br> V = " + v.toString() + "<br>W = " + w.toString();
                    output = v.outerProduct(w).toString();
                } else if(vectorOp.equals("norm")) {
                    ArrayRealVector w = new RealVectorFormat().parse(vectorW);
                    input = "Computer norm of V where:<br> V = " + v.toString();
                    output = v.getNorm() + "";
                }
                break;
                
            case 8:
                String data = request.getParameter("stats");
                SummaryStatistics stats = new SummaryStatistics();
                DescriptiveStatistics stats2 = new DescriptiveStatistics();
                data = StringUtils.deleteWhitespace(data);
                String[] parsedData = StringUtils.split(data, ",");
                for(int i=0; i < parsedData.length; i++)
                {
                    stats.addValue(Double.parseDouble(parsedData[i]));
                    stats2.addValue(Double.parseDouble(parsedData[i]));
                }
                input = "Describe " + data;
                output = stats.toString() + "<br><br>" + stats2.toString();
                break;
        }
        out.println("<h2><u>INPUT</u>:<br>" + input + "</h2><br>");
        out.println("<h2><u>OUTPUT</u>:<br>" + output + "</h2><br>");
%>
<%@ include file="footer.html" %>